using namespace std;
typedef unsigned int uint;
typedef unsigned char uchar;
#include "sha1.phs.h"

void sha1(unsigned char *data, unsigned int lenght,unsigned char digest[20])
{
    unsigned int  H[5]  = {0x67452301,0xefcdab89,0x98badcfe,0x10325476,0xc3d2e1f0};
    unsigned char d[64] = {0} ;
    unsigned int  w[80] = {0} ;
    unsigned int i=0;
    
    while(true)
    {
        unsigned int size = std::min(lenght-i,64U);
        memcpy(d,data+i,size);
        i+=size;
        if(size<64)break;
        SHA1ProcessMessageBlock::generatrix<>::code(d, w, H);
    }
    i=i%64;
    
    /*padding*/
    if (i > 55)
    {
        d[i++] = 0x80;
        while(i < 64)
        {  d[i++] = 0; }
        SHA1ProcessMessageBlock::generatrix<>::code(d, w, H);
        while(i < 56)
        { d[i++] = 0; }
    }
    else
    {
        d[i++] = 0x80;
        while(i < 56)
        { d[i++] = 0; }
    }

    unsigned int Length_High = 0; 
    unsigned int Length_Low  = lenght*8;
    d[56] = Length_High >> 24;
    d[57] = Length_High >> 16;
    d[58] = Length_High >> 8;
    d[59] = Length_High;
    d[60] = Length_Low >> 24;
    d[61] = Length_Low >> 16;
    d[62] = Length_Low >> 8;
    d[63] = Length_Low;

    SHA1ProcessMessageBlock::generatrix<>::code(d, w, H);

     for (unsigned int i = 0; i < 5; i++)
                 ((unsigned int *)digest)[i] = H[i];   
}


